﻿//------------------------------------------------------------------------------
//  Namespace: FruitVentDesign.Controls
//  
//  Function： N/A
//  Name： Input
//  
//  Ver       Time                     Author
//  0.10      2021/6/18 11:52:58      FruitVent
//
//  此代码版权归作者本人FruitVent所有
//  源代码使用协议遵循本仓库的开源协议及附加协议，若本仓库没有设置，则按MIT开源协议授权
//  CSDN博客：https://blog.csdn.net/weixin_39552347
//  源代码仓库：https://gitee.com/fruitvent
//  感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using FruitVentDesign.Commands;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;

namespace FruitVentDesign.Controls
{
    public class Input : TextBox
    {
        static Input()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Input), new FrameworkPropertyMetadata(typeof(Input)));
        }

        #region HasErrorMessage 验证通过与否字段
        /// <summary>
        /// 验证通过与否字段
        /// </summary>
        public static readonly DependencyProperty HasErrorMessageProperty = DependencyProperty.Register(
            "HasErrorMessage", typeof(bool), typeof(Input), new FrameworkPropertyMetadata(false,
                FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                new PropertyChangedCallback(OnHasErrorMessagePropertyChanged)));

        private static void OnHasErrorMessagePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            var oldValue = (object)args.OldValue;
            var newValue = (object)args.NewValue;

            if (oldValue == newValue)
                return;

            if ((bool)newValue)
            {
                if (obj is FrameworkElement content && content.Parent is Form form)
                {
                    if (form.ItemContainerGenerator.ContainerFromItem(content) is FormItem formItem)
                    {
                        formItem.HasErrorMessage = true;
                        var binding = new Binding(nameof(FormItem.ErrorMessage))
                        {
                            Source = content,
                            Mode = BindingMode.TwoWay,
                            Path = new PropertyPath("(Validation.Errors).CurrentItem.ErrorContent")
                        };
                        formItem.SetBinding(FormItem.ErrorMessageProperty, binding);
                    }
                }
            }
            else
            {
                if (obj is FrameworkElement content && content.Parent is Form form)
                {
                    if (form.ItemContainerGenerator.ContainerFromItem(content) is FormItem formItem)
                    {
                        formItem.HasErrorMessage = false;
                    }
                }
            }
        }

        public bool HasErrorMessage
        {
            get => (bool)GetValue(HasErrorMessageProperty);
            set => SetValue(HasErrorMessageProperty, value);
        }

        public static void SetHasErrorMessage(DependencyObject element, bool value)
        {
            element.SetValue(HasErrorMessageProperty, value);
        }

        public static bool GetHasErrorMessage(DependencyObject element)
        {
            return (bool)element.GetValue(HasErrorMessageProperty);
        }
        #endregion

        #region PlaceholderProperty 占位符
        /// <summary>
        /// 占位符
        /// </summary>
        public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.Register(
            "Placeholder", typeof(string), typeof(Input), new FrameworkPropertyMetadata(""));

        public string Placeholder
        {
            get { return (string)GetValue(PlaceholderProperty); }
            set { SetValue(PlaceholderProperty, value); }
        }

        public static string GetPlaceholder(DependencyObject d)
        {
            return (string)d.GetValue(PlaceholderProperty);
        }

        public static void SetPlaceholder(DependencyObject obj, string value)
        {
            obj.SetValue(PlaceholderProperty, value);
        }
        #endregion

        #region CornerRadiusProperty Border圆角
        /// <summary>
        /// Border圆角
        /// </summary>
        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached(
            "CornerRadius", typeof(CornerRadius), typeof(Input), new FrameworkPropertyMetadata(new CornerRadius(3)));

        public CornerRadius CornerRadius
        {
            get { return (CornerRadius)GetValue(CornerRadiusProperty); }
            set { SetValue(CornerRadiusProperty, value); }
        }

        public static CornerRadius GetCornerRadius(DependencyObject d)
        {
            return (CornerRadius)d.GetValue(CornerRadiusProperty);
        }

        public static void SetCornerRadius(DependencyObject obj, CornerRadius value)
        {
            obj.SetValue(CornerRadiusProperty, value);
        }
        #endregion

        #region FocusBorderBrushProperty 焦点边框色，输入控件
        /// <summary>
        /// 焦点边框色，输入控件
        /// </summary>
        public static readonly DependencyProperty FocusBorderBrushProperty = DependencyProperty.Register(
            "FocusBorderBrush", typeof(Brush), typeof(Input), new FrameworkPropertyMetadata(null));

        public Brush FocusBorderBrush
        {
            get { return (Brush)GetValue(FocusBorderBrushProperty); }
            set { SetValue(FocusBorderBrushProperty, value); }
        }

        public static void SetFocusBorderBrush(DependencyObject element, Brush value)
        {
            element.SetValue(FocusBorderBrushProperty, value);
        }

        public static Brush GetFocusBorderBrush(DependencyObject element)
        {
            return (Brush)element.GetValue(FocusBorderBrushProperty);
        }
        #endregion

        #region MouseOverBorderBrushProperty 鼠标进入边框色，输入控件
        /// <summary>
        /// 鼠标进入边框色，输入控件
        /// </summary>
        public static readonly DependencyProperty MouseOverBorderBrushProperty = DependencyProperty.Register(
            "MouseOverBorderBrush", typeof(Brush), typeof(Input),
            new FrameworkPropertyMetadata(Brushes.Transparent,
            FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.Inherits));

        public Brush MouseOverBorderBrush
        {
            get { return (Brush)GetValue(MouseOverBorderBrushProperty); }
            set { SetValue(MouseOverBorderBrushProperty, value); }
        }

        /// <summary>
        /// Sets the brush used to draw the mouse over brush.
        /// </summary>
        public static void SetMouseOverBorderBrush(DependencyObject obj, Brush value)
        {
            obj.SetValue(MouseOverBorderBrushProperty, value);
        }

        /// <summary>
        /// Gets the brush used to draw the mouse over brush.
        /// </summary>
        public static Brush GetMouseOverBorderBrush(DependencyObject obj)
        {
            return (Brush)obj.GetValue(MouseOverBorderBrushProperty);
        }
        #endregion

        #region AttachContentProperty 附加组件模板
        /// <summary>
        /// 附加组件模板
        /// </summary>
        public static readonly DependencyProperty AttachContentProperty = DependencyProperty.Register(
            "AttachContent", typeof(ControlTemplate), typeof(Input), new FrameworkPropertyMetadata(null));

        public ControlTemplate AttachContent
        {
            get { return (ControlTemplate)GetValue(AttachContentProperty); }
            set { SetValue(AttachContentProperty, value); }
        }

        public static ControlTemplate GetAttachContent(DependencyObject d)
        {
            return (ControlTemplate)d.GetValue(AttachContentProperty);
        }

        public static void SetAttachContent(DependencyObject obj, ControlTemplate value)
        {
            obj.SetValue(AttachContentProperty, value);
        }
        #endregion

        #region LabelProperty TextBox的头部Label
        /// <summary>
        /// TextBox的头部Label
        /// </summary>
        public static readonly DependencyProperty LabelProperty = DependencyProperty.Register(
            "Label", typeof(string), typeof(Input), new FrameworkPropertyMetadata(null));

        public string Label
        {
            get { return (string)GetValue(LabelProperty); }
            set { SetValue(LabelProperty, value); }
        }

        public static string GetLabel(DependencyObject d)
        {
            return (string)d.GetValue(LabelProperty);
        }

        public static void SetLabel(DependencyObject obj, string value)
        {
            obj.SetValue(LabelProperty, value);
        }
        #endregion

        #region LabelWidthProperty TextBox的头部Label宽度
        /// <summary>
        /// TextBox的头部Label宽度
        /// </summary>
        public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.RegisterAttached(
            "LabelWidth", typeof(double), typeof(Input), new FrameworkPropertyMetadata(double.NaN));

        public double LabelWidth
        {
            get { return (double)GetValue(LabelWidthProperty); }
            set { SetValue(LabelWidthProperty, value); }
        }

        public static double GetLabelWidth(DependencyObject d)
        {
            return (double)d.GetValue(LabelWidthProperty);
        }

        public static void SetLabelWidth(DependencyObject obj, double value)
        {
            obj.SetValue(LabelWidthProperty, value);
        }
        #endregion

        #region LabelTemplateProperty TextBox的头部Label模板
        /// <summary>
        /// TextBox的头部Label模板
        /// </summary>
        public static readonly DependencyProperty LabelTemplateProperty = DependencyProperty.Register(
            "LabelTemplate", typeof(ControlTemplate), typeof(Input), new FrameworkPropertyMetadata(null));

        public ControlTemplate LabelTemplate
        {
            get { return (ControlTemplate)GetValue(LabelTemplateProperty); }
            set { SetValue(LabelTemplateProperty, value); }
        }

        public static ControlTemplate GetLabelTemplate(DependencyObject d)
        {
            return (ControlTemplate)d.GetValue(LabelTemplateProperty);
        }

        public static void SetLabelTemplate(DependencyObject obj, ControlTemplate value)
        {
            obj.SetValue(LabelTemplateProperty, value);
        }
        #endregion

        #region AllowClearProperty 清除输入框Text值按钮启用
        /// <summary>
        /// 清除输入框Text值按钮显示与否
        /// </summary>
        public static readonly DependencyProperty AllowClearProperty = DependencyProperty.RegisterAttached(
            "AllowClear", typeof(bool), typeof(Input), new FrameworkPropertyMetadata(false, AllowClearChanged));

        public bool AllowClear
        {
            get { return (bool)GetValue(AllowClearProperty); }
            set { SetValue(AllowClearProperty, value); }
        }

        /// <summary>
        /// Gets the brush used to draw the mouse over brush.
        /// </summary>
        public static bool GetAllowClear(DependencyObject d)
        {
            return (bool)d.GetValue(AllowClearProperty);
        }

        public static void SetAllowClear(DependencyObject obj, bool value)
        {
            obj.SetValue(AllowClearProperty, value);
        }

        private static void AllowClearChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != e.NewValue && d is Button button)
            {
                button.CommandBindings.Add(RoutedUICommands.ClearTextCommandBinding);
            }
        }
        #endregion

        #region IsOpenFileButtonBehaviorEnabledProperty 选择文件命令行为开关
        /// <summary>
        /// 选择文件命令行为开关
        /// </summary>
        public static readonly DependencyProperty IsOpenFileButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached(
            "IsOpenFileButtonBehaviorEnabled", typeof(bool), typeof(Input), new FrameworkPropertyMetadata(false, IsOpenFileButtonBehaviorEnabledChanged));

        public static bool GetIsOpenFileButtonBehaviorEnabled(DependencyObject d)
        {
            return (bool)d.GetValue(IsOpenFileButtonBehaviorEnabledProperty);
        }

        public static void SetIsOpenFileButtonBehaviorEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsOpenFileButtonBehaviorEnabledProperty, value);
        }

        private static void IsOpenFileButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != e.NewValue && d is Button button)
            {
                button.CommandBindings.Add(RoutedUICommands.OpenFileCommandBinding);
            }
        }
        #endregion

        #region IsOpenFolderButtonBehaviorEnabledProperty 选择文件夹命令行为开关
        /// <summary>
        /// 选择文件夹命令行为开关
        /// </summary>
        public static readonly DependencyProperty IsOpenFolderButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached(
            "IsOpenFolderButtonBehaviorEnabled", typeof(bool), typeof(Input), new FrameworkPropertyMetadata(false, IsOpenFolderButtonBehaviorEnabledChanged));

        public static bool GetIsOpenFolderButtonBehaviorEnabled(DependencyObject d)
        {
            return (bool)d.GetValue(IsOpenFolderButtonBehaviorEnabledProperty);
        }

        public static void SetIsOpenFolderButtonBehaviorEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsOpenFolderButtonBehaviorEnabledProperty, value);
        }

        private static void IsOpenFolderButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != e.NewValue && d is Button button)
            {
                button.CommandBindings.Add(RoutedUICommands.OpenFolderCommandBinding);
            }
        }
        #endregion

        #region IsSaveFileButtonBehaviorEnabledProperty 选择文件保存路径及名称
        /// <summary>
        /// 选择文件保存路径及名称
        /// </summary>
        public static readonly DependencyProperty IsSaveFileButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached(
            "IsSaveFileButtonBehaviorEnabled", typeof(bool), typeof(Input), new FrameworkPropertyMetadata(false, IsSaveFileButtonBehaviorEnabledChanged));

        public static bool GetIsSaveFileButtonBehaviorEnabled(DependencyObject d)
        {
            return (bool)d.GetValue(IsSaveFileButtonBehaviorEnabledProperty);
        }

        public static void SetIsSaveFileButtonBehaviorEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsSaveFileButtonBehaviorEnabledProperty, value);
        }

        private static void IsSaveFileButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != e.NewValue && d is Button button)
            {
                button.CommandBindings.Add(RoutedUICommands.SaveFileCommandBinding);
            }
        }
        #endregion
    }
}
